package com.yanqu.road.dao.impl.player;

import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.dao.impl.TempDataObjectDao;
import com.yanqu.road.dao.impl.logic.ResultSetParseEntityManger;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class UserPatronsDaoImpl extends TempDataObjectDao<UserPatrons> {

	public Map<Integer, UserPatrons> getUserPatronsMap(long userId) {
		Map<Integer, UserPatrons> dataMap = new ConcurrentHashMap<>();
		ResultSet rs = null;
		CallableStatement call = null;
		String sql = "select * from t_u_patrons where userId = ?";
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareCall(sql);
			call.setLong(1, userId);
			rs = call.executeQuery();
			while (rs.next()) {
				UserPatrons data = parse(rs);
				dataMap.put(data.getPatronsId(), data);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return dataMap;
	}

	public Map<Long,Map<Integer, UserPatrons>> getSomeUserPatronsMap(List<Long> userIdList) {
		Map<Long,Map<Integer, UserPatrons>> dataMap = new ConcurrentHashMap<>();
		if(userIdList.size() == 0){
			return dataMap;
		}
		ResultSet rs = null;
		CallableStatement call = null;
		String sql = "select * from t_u_patrons where userId in("+ StringUtils.listToString(userIdList,",") +") ";
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareCall(sql);
			rs = call.executeQuery();
			while (rs.next()) {
				UserPatrons data = parse(rs);
				if(!dataMap.containsKey(data.getUserId())){
					dataMap.put(data.getUserId(),new ConcurrentHashMap<>());
				}
				dataMap.get(data.getUserId()).put(data.getPatronsId(), data);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return dataMap;
	}

	public UserPatrons getUserPatrons(long userId,int patronsId) {
		ResultSet rs = null;
		CallableStatement call = null;
		String sql = "select * from t_u_patrons where userId = ? and patronsId = ?";
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareCall(sql);
			call.setLong(1, userId);
			call.setLong(2, patronsId);
			rs = call.executeQuery();
			if (rs.next()) {
				return parse(rs);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return null;
	}

	public Map<Integer, UserPatrons> getUserPatronsMap(long userId, List<Integer> patronIdList) {
		Map<Integer, UserPatrons> dataMap = new ConcurrentHashMap<>();
		ResultSet rs = null;
		CallableStatement call = null;
		String sql = "select * from t_u_patrons where userId = ?";
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareCall(sql);
			call.setLong(1, userId);
			rs = call.executeQuery();
			while (rs.next()) {
				UserPatrons data = parse(rs);
				if(patronIdList.contains(data.getPatronsId())){
					dataMap.put(data.getPatronsId(), data);
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return dataMap;
	}

	@Override
	protected boolean addData(UserPatrons data) {
		PreparedStatement call = null;
		String sql = "INSERT INTO t_u_patrons(userId,patronsId,level,stageLv,ability,breakLv,qualification,addAbility,tradeWarAddEarnSpeed,skinId," +
				"unionTradeSend,resetTime,cookExp,baiYeExp,tradeWarLoseScoreReduce,chouSuanExp,promotionId,teacherExp,grandChildSpeed,isLinkageSwitch,keepSakeAddition,keepSakePatronsId,keepSakeTime,itemAddQualification" +
				") VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareStatement(sql);
			int i = 1;
			call.setLong(i++, data.getUserId());
			call.setInt(i++, data.getPatronsId());
			call.setInt(i++, data.getLevel());
			call.setInt(i++, data.getStageLv());
			call.setString(i++, data.getAbility().toString());
			call.setInt(i++, data.getBreakLv());
			call.setLong(i++, data.getQualification());
			call.setString(i++, data.getAddAbility().toString());
			call.setString(i++, data.getTradeWarAddEarnSpeed().toString());
			call.setInt(i++, data.getSkinId());
			call.setBoolean(i++, data.isUnionTradeSend());
			call.setLong(i++, data.getResetTime());
			call.setLong(i++,data.getCookExp());
			call.setLong(i++, data.getBaiYeExp());
			call.setLong(i++, data.getTradeWarLoseScoreReduce());
			call.setLong(i++, data.getChouSuanExp());
			call.setInt(i++,data.getPromotionId());
			call.setLong(i++,data.getTeacherExp());
			call.setString(i++,data.getGrandChildSpeed().toString());
			call.setBoolean(i++, data.isLinkageSwitch());
			call.setLong(i++, data.getKeepSakeAddition());
			call.setInt(i++, data.getKeepSakePatronsId());
			call.setInt(i++, data.getKeepSakeTime());
			call.setLong(i++, data.getItemAddQualification());
			return call.executeUpdate() > 0;
		} catch (Exception e) {
			logger.error(Thread.currentThread().getStackTrace()[1].getMethodName() + ":", e);
		} finally {
			getDb().closeConnection(call, null);
		}
		return false;
	}

	@Override
	protected boolean updateData(UserPatrons data) {
		PreparedStatement call = null;
		String sql = "UPDATE t_u_patrons SET level=?,stageLv=?,ability=?,breakLv=?,qualification=?,addAbility=?,tradeWarAddEarnSpeed=?,skinId=?," +
				"unionTradeSend=?,resetTime=?,cookExp=?,baiYeExp=?,tradeWarLoseScoreReduce=?,chouSuanExp=?,promotionId=?,teacherExp=?," +
				"grandChildSpeed=?,isLinkageSwitch=?,keepSakeAddition=?,keepSakePatronsId=?,keepSakeTime=?,itemAddQualification=? WHERE userId=? and patronsId=?";
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareStatement(sql);
			int i = 1;
			call.setInt(i++, data.getLevel());
			call.setInt(i++, data.getStageLv());
			call.setString(i++, data.getAbility().toString());
			call.setInt(i++, data.getBreakLv());
			call.setLong(i++, data.getQualification());
			call.setString(i++, data.getAddAbility().toString());
			call.setString(i++, data.getTradeWarAddEarnSpeed().toString());
			call.setInt(i++, data.getSkinId());
			call.setBoolean(i++, data.isUnionTradeSend());
			call.setLong(i++, data.getResetTime());
			call.setLong(i++,data.getCookExp());
			call.setLong(i++, data.getBaiYeExp());
			call.setLong(i++, data.getTradeWarLoseScoreReduce());
			call.setLong(i++, data.getChouSuanExp());
			call.setInt(i++,data.getPromotionId());
			call.setLong(i++, data.getTeacherExp());
			call.setString(i++, data.getGrandChildSpeed().toString());
			call.setBoolean(i++, data.isLinkageSwitch());
			call.setLong(i++, data.getKeepSakeAddition());
			call.setInt(i++, data.getKeepSakePatronsId());
			call.setInt(i++, data.getKeepSakeTime());
			call.setInt(i++, data.getItemAddQualification());
			call.setLong(i++, data.getUserId());
			call.setInt(i++, data.getPatronsId());

			return call.executeUpdate() > 0;
		} catch (Exception e) {
			logger.error(Thread.currentThread().getStackTrace()[1].getMethodName() + ":fail ", e);
		} finally {
			getDb().closeConnection(call, null);
		}
		return false;
	}

	@Override
	protected UserPatrons parseData(ResultSet rs) throws SQLException {
		return ResultSetParseEntityManger.initUserPatrons(rs);
	}


	public List<UserPatrons> getUserPatronsList(List<String> patronsIdList) {
		List<UserPatrons> list = new ArrayList<>();
		ResultSet rs = null;
		CallableStatement call = null;
		//todo 先这样写，下次有用到这个的时候改
		long todayZeroTimeStamp = DateHelper.getTodayZeroTimeStamp();
		long t = todayZeroTimeStamp / 1000 - (long) 3 * 24 * 60 * 60;
		String sql = "select userId, patronsId, ability from t_u_patrons where userId in (select userId from t_u_user where lastLoginTime >= ?)";
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareCall(sql);
			call.setLong(1, t);
			rs = call.executeQuery();
			while (rs.next()) {
				UserPatrons data = new UserPatrons();
				data.setUserId(rs.getLong("userId"));
				data.setPatronsId(rs.getInt("patronsId"));
				String value = rs.getString("ability");
				if(!StringUtils.isNullOrEmpty(value)) {
					data.setAbility(new BigInteger(value));
				}
				list.add(data);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return list;
	}





	public Map<Long, Long> getActiveUserPatronsAbility(int lastLoginTime, int title){
		String sql = "select userId, totalAbility from t_u_user where lastLoginTime >= ? and titleId >= ? GROUP BY userId ";
		ResultSet rs = null;
		CallableStatement call = null;
		Map<Long, Long> userPatronsAbilityMap = new HashMap<>();
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareCall(sql);
			call.setLong(1, lastLoginTime);
			call.setInt(2, title);
			rs = call.executeQuery();
			while (rs.next()) {
				long userId = rs.getLong("userId");
				long allAbility = rs.getLong("totalAbility");
				userPatronsAbilityMap.put(userId, allAbility);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return userPatronsAbilityMap;
	}

	/**
	 * 获取门客前n名
	 * @param userId
	 * @param n
	 * @return
	 */
	public List<UserPatrons> getTopNUserPatronsList(long userId, int n) {
		List<UserPatrons> dataList = new ArrayList<>();
		ResultSet rs = null;
		CallableStatement call = null;
		String sql = "select * from t_u_patrons where userId = ? order by CAST(ability AS UNSIGNED) desc limit " + n;
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareCall(sql);
			call.setLong(1, userId);
			rs = call.executeQuery();
			while (rs.next()) {
				UserPatrons data = parse(rs);
				dataList.add(data);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return dataList;
	}
}
